#include "structEdges.hpp"
#include "structMesh.hpp"

namespace hms {

StructEdges::StructEdges( const StructMesh& mesh ) :
	StructEdgesBase<StructEdges>(mesh)
{}


auto StructEdges::lengthsImp() const -> LengthsReturnType { return m_lengths; }
auto StructEdges::normalsImp() const -> NormalsReturnType { return m_normals; }

auto StructEdges::length(Index i) const -> scalar {
	return m_lengths(i);
}

auto StructEdges::normal(Index i) const -> Matrix2Xs::ConstColXpr {
	return m_normals.col(i);
}

void StructEdges::storeData(){
	storeLengths();
	storeNormals();
	storeIndices();
}

void StructEdges::storeLengths() {
	assert( m_lengths.size() == 0 );
	
	m_lengths.resize( mesh().nEdges() );

	for ( Index i=0; i<mesh().nEdges(); ++i ){
		m_lengths(i) = (
				mesh().vertex(mesh().edge(i).vertices()[0]) -
				mesh().vertex(mesh().edge(i).vertices()[1])
			).norm();
	}
}

void StructEdges::storeNormals() {
	assert( m_normals.size() == 0 );
	m_normals.resize( NoChange, mesh().nEdges() );

	for (Index i{0}; i<mesh().nEdges(); ++i){
		/* normal() produces a leftward pointing normal vector */
		m_normals.col(i) = Line::Through(
			mesh().vertex( mesh().edge(i).vertices()[0] ),
			mesh().vertex( mesh().edge(i).vertices()[1] )
		).normal();

		/* now only the orientation has to be adjusted to make normal vectors
		 * always point from the cell with the lower index to the one with the
		 * higher index */
		if (mesh().edge(i).range() == EdgeRange::vertical)
			m_normals.col(i) *= -1;
	}
}


}